package cn.lysj.framework.order.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.date.DateUtil;
import cn.lysj.framework.base.BaseService;
import cn.lysj.framework.common.OrderPayConstant;
import cn.lysj.framework.common.domain.User;
import cn.lysj.framework.common.service.UserService;
import cn.lysj.framework.common.utils.http.HttpUtil;
import cn.lysj.framework.common.utils.json.GsonUtil;
import cn.lysj.framework.common.utils.json.JacksonUtil;
import cn.lysj.framework.common.utils.pagination.PageUtil;
import cn.lysj.framework.common.utils.pagination.PageVo;
import cn.lysj.framework.common.utils.random.RandomUtil;
import cn.lysj.framework.common.utils.web.ParamUtil;
import cn.lysj.framework.common.utils.web.Resp;

import cn.lysj.framework.common.utils.websocket.IncidentType;
import cn.lysj.framework.common.utils.websocket.WebSocketServerToUser;
import cn.lysj.framework.config.domain.Config;
import cn.lysj.framework.config.service.ConfigService;
import cn.lysj.framework.customer.domain.Customer;
import cn.lysj.framework.customer.domain.CustomerInfo;
import cn.lysj.framework.customer.domain.CustomerVip;
import cn.lysj.framework.customer.repository.CustomerRepository;
import cn.lysj.framework.customer.service.CustomerInfoService;
import cn.lysj.framework.customer.service.CustomerService;
import cn.lysj.framework.customer.service.CustomerVipService;
import cn.lysj.framework.elm.base.ElmContent;
import cn.lysj.framework.elm.domain.ElmFoodDetail;
import cn.lysj.framework.elm.domain.ElmOrder;
import cn.lysj.framework.elm.elmenum.ElmOrderStatus;
import cn.lysj.framework.elm.elmenum.ElmPrint;
import cn.lysj.framework.foodv2.domain.Food;
import cn.lysj.framework.foodv2.domain.FoodType;
import cn.lysj.framework.foodv2.domain.StandardLevTwo;
import cn.lysj.framework.foodv2.repository.FoodRepository;
import cn.lysj.framework.foodv2.repository.FoodTypeRepository;
import cn.lysj.framework.foodv2.repository.StandardLevTwoRepository;
import cn.lysj.framework.foodv2.service.FoodService;
import cn.lysj.framework.order.domain.FoodOrder;
import cn.lysj.framework.order.domain.FoodOrderInfo;
import cn.lysj.framework.order.dto.AjaxResp;
import cn.lysj.framework.order.dto.AliRefundDto;
import cn.lysj.framework.order.dto.RefundParam;
import cn.lysj.framework.order.json.Child;
import cn.lysj.framework.order.json.FoodOrderJsonBean;
import cn.lysj.framework.order.repository.FoodOrderInfoRepository;
import cn.lysj.framework.order.repository.FoodOrderRepository;
import cn.lysj.framework.order.util.wx.UnifiedOrderUtil;
import cn.lysj.framework.order.util.wx.WXPayUtil;
import cn.lysj.framework.order.util.wx.WxPublicUtil;
import cn.lysj.framework.order.vo.FoodOrderInfoVo;
import cn.lysj.framework.order.vo.FoodOrderVo;
import cn.lysj.framework.order.vo.OrderInfoVo;
import cn.lysj.framework.pirpraph.domain.FoodReport;
import cn.lysj.framework.pirpraph.service.FoodReportService;
import cn.lysj.framework.store.domain.CustEatTable;
import cn.lysj.framework.store.domain.EatTable;
import cn.lysj.framework.store.domain.Store;
import cn.lysj.framework.store.repository.StoreRepository;
import cn.lysj.framework.store.service.CustEatTableService;
import cn.lysj.framework.store.service.EatTableService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.transaction.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zwj
 * @description 订单服务层
 * @create 2018-11-05 09:51:42
 **/
@Slf4j
@Service
@Transactional
public class FoodOrderService implements BaseService<FoodOrder> {

    private static String returnOrderURL = "https://mp.changepay.cn/wxpay/refund";

    @Resource
    private FoodService foodService;
    @Resource
    private FoodOrderRepository foodOrderRepository;
    @Resource
    private FoodOrderInfoService foodOrderInfoService;
    @Resource
    private StandardLevTwoRepository standardLevTwoRepository;
    @Resource
    private EatTableService eatTableService;
    @Resource
    private CustomerRepository customerRepository;
    @Resource
    private CustEatTableService custEatTableService;
    @Resource
    private ConfigService configService;
    @Resource
    private UserService userService;
    @Resource
    private StoreRepository storeRepository;
    @Resource
    private  FoodTypeRepository foodTypeRepository;
    @Resource
    private FoodReportService foodReportService;
    @Resource
    private CustomerService customerService;
    @Resource
    private CustomerInfoService customerInfoService;
    @Resource
    private CustomerVipService customerVipService;

    @Resource
    protected ElmContent elmContent;


    @Override
    public FoodOrderRepository getRepository() {
        return foodOrderRepository;
    }

    public Resp list(User user) {
        List<FoodOrder> foodOrders = foodOrderRepository.findByStoreIdAndFoodOrderStatusNot(user.getStoreId(), -1);
        return new Resp(foodOrders);
    }

    //查看订单
    public Resp showFoodOrder(String customerId, String storeId, PageVo pageVo) {
        if (ParamUtil.isBlank(customerId)) {
            return new Resp(Resp.NO_LOGIN, "用户信息有误!");
        }
        Customer customer = customerRepository.findOne(customerId);
        if (customer == null) {
            return new Resp(Resp.NO_LOGIN, "用户信息有误!");
        }
        if (ParamUtil.isBlank(storeId)) {
            return new Resp(Resp.PARAM_ERROR, "未获取商铺Id");
        }
        Pageable pageable = PageUtil.initPage(pageVo);
        Integer[] status = new Integer[1];
        status[0] = -2;
        Page<FoodOrder> foodOrders = foodOrderRepository.findByCustomerIdAndStoreIdAndFoodOrderStatusNotInOrderByCreateTimeDesc(pageable, customerId, storeId, status);
        List<FoodOrderVo> foodOrderVos = new ArrayList<>();
        for (FoodOrder foodOrder : foodOrders) {
            addFoodOrderVos(foodOrderVos, foodOrder);
        }
        Map<String, Object> respMap = new HashMap();
        respMap.put("total", foodOrders.getTotalElements());
        respMap.put("rows", foodOrderVos);
        return new Resp(respMap);
    }

    //查看订单工具类
    public void addFoodOrderVos(List<FoodOrderVo> foodOrderVos, FoodOrder foodOrder) {
        FoodOrderVo foodOrderVo = new FoodOrderVo();
        BeanUtils.copyProperties(foodOrder, foodOrderVo);
        List<FoodOrderInfoVo> foodOrderInfoVos = platFoodOrderInfoQuery(foodOrder.getId());
        foodOrderVo.setFoodOrderInfoVos(foodOrderInfoVos);
        foodOrderVos.add(foodOrderVo);
    }

    //订单详情查看方法类
    public List<FoodOrderInfoVo> platFoodOrderInfoQuery(String foodOrderId) {
        List<FoodOrderInfo> foodOrderInfos = foodOrderInfoService.getRepository().findFoodOrderInfoList(foodOrderId);
        List<FoodOrderInfoVo> foodOrderInfoVos = new LinkedList<>();
        for (FoodOrderInfo foodOrderInfo : foodOrderInfos) {
            FoodOrderInfoVo foodOrderInfoVo = new FoodOrderInfoVo();
            BeanUtils.copyProperties(foodOrderInfo, foodOrderInfoVo);
            foodOrderInfoVo.setStandardLevTwoIds(foodOrderInfo.getStandardLevTwoIds().split(","));
            foodOrderInfoVos.add(foodOrderInfoVo);
        }
        return foodOrderInfoVos;
    }


    //添加订单
    public Resp addFoodOrder(String data, String customerId, String eatTableId, String custEatTableId) {
        if (ParamUtil.isBlank(customerId)) {
            return new Resp(Resp.NO_LOGIN, "用户信息出错!");
        }
        Customer customer = customerRepository.findOne(customerId);
        if (customer == null) {
            return new Resp(Resp.NO_LOGIN, "未获取到用户信息!");
        }
        if (ParamUtil.isBlank(eatTableId)) {
            return new Resp(Resp.PARAM_ERROR, "桌号信息出错!");
        }
        EatTable eatTable = eatTableService.findOne(eatTableId);
        if (eatTable == null) {
            return new Resp(Resp.PARAM_ERROR, "该桌号信息获取失败!");
        }
        List<FoodOrderJsonBean> foodOrderJsonBeans = GsonUtil.toList(data, FoodOrderJsonBean.class);
        //保存当前订单信息
        FoodOrder foodOrder = new FoodOrder();
        //功能编号1：修改foodOrder实体类
        changeFoodOrderInAddFoodOrder(foodOrder, eatTableId, eatTable, customer, custEatTableId);
        //编号1结束

        //功能编号2：多人拼单部分判断是否已经下单结算,已经下过单则判断不通过 主要用于通知桌内某人已经支付完毕了
        if (!ParamUtil.isBlank(custEatTableId)) {
            CustEatTable custEatTable = custEatTableService.findOne(custEatTableId);
            if (custEatTable == null) {
                return new Resp(Resp.PARAM_ERROR, "下单失败,桌号数据异常!");
            }
            sendMsgToCustEatTableUser(custEatTable, customerId, customer.getNickName());
        }
        //编号2结束
        //保存foodOrder
        foodOrder = foodOrderRepository.save(foodOrder);

        //功能编号3：①:构建具体食物详情foodOrderInfos  ②:修改foodOrder 的 1.餐盒费：allBoMoney 2.应付金额：sumMoney 3.食品拼接名称：subject
        List<FoodOrderInfo> foodOrderInfos = new LinkedList<>();
        String result = addFoodOrderInfos(foodOrderJsonBeans, foodOrderInfos, foodOrder);
        if (!ParamUtil.isBlank(result)) {
            return new Resp(Resp.PARAM_ERROR, result);
        }
        //编号3结束

        foodOrderInfoService.save(foodOrderInfos);
        //更新时间
        foodOrderRepository.save(foodOrder);

        //功能编号4：构建该订单完成类返回前端订单数据
        List<FoodOrderVo> foodOrderVos = new ArrayList<>();
        addFoodOrderVos(foodOrderVos, foodOrder);
        //编号4结束
        return new Resp(foodOrderVos);
    }

    //构建foodOrderInfos
    public String addFoodOrderInfos(List<FoodOrderJsonBean> foodOrderJsonBeans, List<FoodOrderInfo> foodOrderInfos, FoodOrder foodOrder) {
        String result = "";
        int number = 0;
        for (FoodOrderJsonBean foodOrderJsonBean : foodOrderJsonBeans) {
            List<Child> children = foodOrderJsonBean.getChild();
            for (Child child : children) {
                BigDecimal foodOrderInfoMoney = BigDecimal.ZERO;
                String standardLevTwoIds = "";
                String standardLevTwoIdNames = "";
                FoodOrderInfo foodOrderInfo = new FoodOrderInfo();
                foodOrderInfo.setFoodOrderId(foodOrder.getId());
                foodOrderInfo.setFoodTypeId(foodOrderJsonBean.getParentId());
                Food food = foodService.findOne(child.getId());
                if (food == null) {
                    foodOrderRepository.delete(foodOrder.getId());
                    return child.getName() + "没有啦,请重新选单!";
                } else if (food.getOnSale() == -1) {
                    foodOrderRepository.delete(foodOrder.getId());
                    return child.getName() + "售罄了,请重新选单!";
                } else {
                    foodOrderInfoMoney = foodOrderInfoMoney.add(food.getMoney().multiply(new BigDecimal(child.getOrderNum())));
                    foodOrderInfo.setFoodId(food.getId());
                    foodOrderInfo.setFoodName(food.getName());
                    foodOrderInfo.setNumber(child.getOrderNum());
                    foodOrderInfo.setStatus(1);
                    if (ParamUtil.isBlank(foodOrder.getSubject())) {
                        foodOrder.setSubject(foodOrder.getSubject() + food.getName());
                    } else {
                        foodOrder.setSubject(foodOrder.getSubject() + "," + food.getName());
                    }
                    for (String standardLevTwoId : child.getCheckerList()) {
                        StandardLevTwo standardLevTwo = standardLevTwoRepository.findOne(standardLevTwoId);
                        if (standardLevTwo == null) {
                            return "订单添加失败,菜品信息更新,请重新扫码!";
                        }
                        foodOrderInfoMoney = foodOrderInfoMoney.add(standardLevTwo.getMoney().multiply(new BigDecimal(child.getOrderNum())));
                        if (ParamUtil.isBlank(standardLevTwoIds)) {
                            standardLevTwoIds += standardLevTwo.getId();
                            standardLevTwoIdNames += standardLevTwo.getName();
                        } else {
                            standardLevTwoIds += "," + standardLevTwo.getId();
                            standardLevTwoIdNames += "," + standardLevTwo.getName();
                        }
                    }
                    foodOrderInfo.setStandardLevTwoIds(standardLevTwoIds);
                    foodOrderInfo.setStandardLevTwoIdNames(standardLevTwoIdNames);
                    foodOrderInfo.setMoney(foodOrderInfoMoney);
                    foodOrder.setSumMoney(foodOrder.getSumMoney().add(foodOrderInfoMoney));
                }
                foodOrderInfos.add(foodOrderInfo);
                FoodType foodType = foodTypeRepository.findOne(foodOrderInfo.getFoodTypeId());
                if (foodType.getPriority() != 2) {
                    number += child.getOrderNum();
                }
            }
        }
        //计算外带费与餐盒费
        changeFoodOrderBoMoneyAndCutleryMoney(foodOrder, new BigDecimal(number));
        return result;
    }

    //添加餐盒费与外带费模块
    public void changeFoodOrderBoMoneyAndCutleryMoney(FoodOrder foodOrder, BigDecimal number) {
        Config config = configService.getRepository().findByStoreId(foodOrder.getStoreId());
        foodOrder.setAllBoMoney(config.getBoMoney().multiply(number));
        foodOrder.setAllCutleryMoney(config.getCutleryMoney());
    }

    //改变foodOrder字段
    public void changeFoodOrderInAddFoodOrder(FoodOrder foodOrder, String eatTableId, EatTable eatTable, Customer customer, String custEatTableId) {
        foodOrder.setCustomerId(customer.getId());//用户Id
        foodOrder.setFoodOrderNumber(RandomUtil.createOrderCode(11));//订单号
        foodOrder.setFoodOrderStatus(-2);
        foodOrder.setEatTableId(eatTableId);
        foodOrder.setSumMoney(BigDecimal.ZERO);
        foodOrder.setAllBoMoney(BigDecimal.ZERO);
        foodOrder.setSubject("");
        foodOrder.setCustomerVipCouponId("");
        foodOrder.setDiscountMoney(BigDecimal.ZERO);
        foodOrder.setSerialNumber(eatTable.getSerialNumber());
        foodOrder.setEatTableName(eatTable.getName());
        foodOrder.setRepastWay(1);
        foodOrder.setPayWay(customer.getCustomerType());
        foodOrder.setSumMoney(BigDecimal.ZERO);
        foodOrder.setRefundMoney(BigDecimal.ZERO);
        foodOrder.setStoreId(eatTable.getStoreId());
        foodOrder.setUseFoodNumber(0);
        foodOrder.setPrintType(1);
        foodOrder.setCustEatTableId(custEatTableId);
    }

    //通知桌内其他人已经支付完成了
    public void sendMsgToCustEatTableUser(CustEatTable custEatTable, String customerId, String name) {
        String[] objectIds = custEatTable.getInitiatorId().split("-");
        for (int i = objectIds.length - 1; i >= 0; i--) {
            if (objectIds[i].equals(customerId)) {
                objectIds = (String[]) ArrayUtils.remove(objectIds, i);
                break;
            }
        }
        Integer number = WebSocketServerToUser.sendDataToMorePeopleArray(IncidentType.PAID, name + "进行了付款!", objectIds, custEatTable.getId());
    }

    /**
     * @author drj
     * @date 2018/11/19 10:09
     * @Description:商户后台查询订单
     */
    public Resp showStoreOrders(String userId, Integer status, PageVo pageVo) {
        if (ParamUtil.isBlank(userId)) {
            return new Resp(Resp.PARAM_ERROR, "参数错误");
        }
        User user = userService.findOne(userId);
        if (null == user) {
            return new Resp(Resp.PARAM_ERROR, "未知错误");
        }
        Store store = storeRepository.findOne(user.getStoreId());
        if (null == store) {
            return new Resp(Resp.PARAM_ERROR, "未知错误");
        }

        //用于返回前端总List
        List<OrderInfoVo> orderInfoVos = new ArrayList<>();
        Pageable pageable;
        if(status == 1){
            //用于新订单查询的分页
            Sort s = new Sort(Sort.Direction.DESC, "createTime");
            pageable = new PageRequest(0, pageVo.getPageSize() * pageVo.getPageNumber(), s);
        }
        else{
            //用于其他状态查询的分页
            Sort s = new Sort(Sort.Direction.DESC, "updateTime");
            pageable = new PageRequest(pageVo.getPageNumber() - 1, pageVo.getPageSize(), s);
        }
        //平台订单
        Page<FoodOrder> foodOrders;
        //饿了么订单
        Page<ElmOrder> elmOrders;
        //用于记录条数
        long total = 0;
        //查询各个类型数据
        switch (status){
            case 3:
                //查看申请退款的订单
                foodOrders = foodOrderRepository.findByStoreIdAndFoodOrderStatus(pageable, store.getId(), status);
                break;
            case 6:
                //查看已完成定
                Integer[] typeIds = new Integer[3];
                typeIds[0] = 2; //已结单
                typeIds[1] = 4; //退款成功
                typeIds[2] = 5; //退款失败
                foodOrders = foodOrderRepository.findByStoreIdAndFoodOrderStatusIn(pageable, store.getId(), typeIds);
                break;
            case 1:
                //查看新订单
                Integer[] newOrderStatus = new Integer[2];
                newOrderStatus[0] = 1; //已支付
                newOrderStatus[1] = 6; //线下未支付
                foodOrders = foodOrderRepository.findByStoreIdAndFoodOrderStatusIn(pageable, store.getId(), newOrderStatus);
                //饿了么平台显示已生效跟已接单的订单
                Integer[] elmTypeIds = new Integer[1];
                elmTypeIds[0] = ElmOrderStatus.ACCECPT.getCode();
                elmOrders = elmContent.elmOrderService.getRepository().findByStoreIdAndOrderStatusIn(store.getId(), elmTypeIds, pageable);
                //将饿了么订单记录汇总
                for (ElmOrder elmOrder : elmOrders) {
                    elmAddOrderInfoVo(orderInfoVos, elmOrder);
                }
                total += elmOrders.getTotalElements();
                break;
            default:
                return new Resp(Resp.PARAM_ERROR,"查询状态异常!");
        }
        //平台记录添加
        for (FoodOrder foodOrder : foodOrders) {
            addOrderInfoVo(orderInfoVos, foodOrder);
        }
        Map<String, Object> respMap = new HashMap();
        //新订单查询与其他类型查询分开处理
        if(status == 1){
            //新订单
            // 运用流加快性能
            orderInfoVos = orderInfoVos.stream().sorted((OrderInfoVo a, OrderInfoVo b) -> b.getCreateTime().compareTo(a.getCreateTime())).collect(Collectors.toList());
            //取对应页数数据
            total += foodOrders.getTotalElements();
            int begin = pageVo.getPageSize() * (pageVo.getPageNumber() - 1);
            int end = begin + pageVo.getPageSize() - 1;

            //如果最大条数大于区间 将有区间设置为最尾条
            List<OrderInfoVo> returnOrderInfoVo = new LinkedList<>();
            if (end > orderInfoVos.size() - 1) {
                end = (orderInfoVos.size() - 1);
            }
            //拿出对应区间的N条记录
            for (int i = begin; i <= end; i++) {
                returnOrderInfoVo.add(orderInfoVos.get(i));
            }
            respMap.put("total", total);
            respMap.put("rows", returnOrderInfoVo);
        }
        else{
            //其他类型查询
            respMap.put("total", foodOrders.getTotalElements());
            respMap.put("rows", orderInfoVos);
        }
        return new Resp(respMap);
    }

    /**
     * @param storeId
     * @return cn.lysj.framework.common.utils.web.Resp
     * @author ZhangWenJian
     * @date 2019/1/7 14:05
     * @title showPrintOrder
     * @description 构建历史订单提醒类
     */
    public Resp showPrintOrder(String storeId) {
        Map<String, Object> map = new HashMap<>();
        //查询平台订单
        Integer[] typeIds = new Integer[2];
        typeIds[0] = 1; //已支付
        typeIds[1] = 6; //线下未支付
        //用于返回前端总List
        List<OrderInfoVo> orderInfoVos = new ArrayList<>();
        //1.平台订单部分
        List<FoodOrder> foodOrders = foodOrderRepository.findByPrintTypeAndStoreIdAndFoodOrderStatusInOrderByCreateTimeDesc(1, storeId, typeIds);
        pollPlatFoodOrder(orderInfoVos, foodOrders);
        //饿了么订单
        Integer[] elmTypeIds = new Integer[1];
        elmTypeIds[0] = ElmOrderStatus.ACCECPT.getCode();
        List<ElmOrder> elmOrderList = elmContent.elmOrderService.getRepository().findByStoreIdAndPrintAndOrderStatusInOrderByCreateTimeDesc(storeId, ElmPrint.UNPRINT.getCode(),elmTypeIds);
        pollElmFoodOrder(orderInfoVos, elmOrderList);
        map.put("orderInfo", orderInfoVos);
        Date nowTime = new Date();
        map.put("date", nowTime);
        return new Resp(map);
    }


    /*
     * @author ZhangWenJian
     * @date 2019/2/14 17:02
     * @title newFoodOrder
     * @param storeId
     * @param showTime
     * @return cn.lysj.framework.common.utils.web.Resp
     * @description 用户轮询接口
     */
    public Resp newFoodOrder(String storeId, long showTime) {
        //所查询订单状态
        Integer[] typeIds = new Integer[2];
        typeIds[0] = 1; //已支付
        typeIds[1] = 6; //线下未支付
        //----------轮询时间操作部分-------
        Date queryTime;
        if (ParamUtil.isBlank(showTime)) {
            queryTime = new Date();
        } else {
            queryTime = new Date(showTime);
        }
        Date nowTime = new Date();
        //当前时间-1s
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(nowTime);
        calendar.add(Calendar.SECOND, -1);
        nowTime = calendar.getTime();
        //判断查询开始时间与当前时间-1秒比较，若查询头时间大于尾时间，直接返回
        if (queryTime.getTime() > nowTime.getTime()) {
            Map<String, Object> map = new HashMap<>();
            List<ElmOrder> elmOrderList = new ArrayList<>();
            List<FoodOrderVo> foodOrderVos = new ArrayList<>();
            map.put("elmOrder", elmOrderList);
            map.put("platOrder", foodOrderVos);
            map.put("date", queryTime);
            return new Resp(map);
        }
        //----------各类订单模块----------
        //用于返回前端总List
        List<OrderInfoVo> orderInfoVos = new ArrayList<>();
        //1.平台订单部分
        List<FoodOrder> foodOrders = foodOrderRepository.getNewFoodOrders(storeId, typeIds, queryTime, nowTime);
        pollPlatFoodOrder(orderInfoVos, foodOrders);
        //2.饿了么订单
        Integer[] elmTypeIds = new Integer[1];
        elmTypeIds[0] = ElmOrderStatus.ACCECPT.getCode();
        List<ElmOrder> elmOrderList = elmContent.elmOrderService.getRepository().getNewFoodOrders(storeId, elmTypeIds, queryTime, nowTime);
        pollElmFoodOrder(orderInfoVos, elmOrderList);
        Map<String, Object> map = new HashMap<>();
        map.put("orderInfo", orderInfoVos);
        map.put("date", nowTime);
        return new Resp(map);
    }

    //平台订单查看操作类
    public void pollPlatFoodOrder(List<OrderInfoVo> orderInfoVos, List<FoodOrder> foodOrders) {
        List<FoodOrder> foodChangeOrders = new LinkedList<>();
        for (FoodOrder foodOrder : foodOrders) {
            addOrderInfoVo(orderInfoVos, foodOrder);
            if (foodOrder.getPrintType() == 1) {
                foodOrder.setPrintType(2);
                foodChangeOrders.add(foodOrder);
            }
        }
        foodOrderRepository.save(foodChangeOrders);
    }


    public void pollElmFoodOrder(List<OrderInfoVo> orderInfoVos, List<ElmOrder> elmOrders) {
        List<ElmOrder> elmOrderList = new LinkedList<>();
        for (ElmOrder elmOrder : elmOrders) {
            elmAddOrderInfoVo(orderInfoVos, elmOrder);
            if (ElmPrint.UNPRINT.getCode().equals(elmOrder.getPrint())) {
                elmOrder.setPrint(ElmPrint.PRINTSUCCESS.getCode());
                elmOrderList.add(elmOrder);
            }
        }
        elmContent.elmOrderService.getRepository().save(elmOrderList);
    }


    //查看平台订单工具类
    public void addOrderInfoVo(List<OrderInfoVo> orderInfoVos, FoodOrder foodOrder) {
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        CopyOptions copyOptions = new CopyOptions();
        copyOptions.setIgnoreNullValue(true);
        BeanUtil.copyProperties(foodOrder, orderInfoVo, copyOptions);
        List<FoodOrderInfoVo> foodOrderInfoVos = platFoodOrderInfoQuery(foodOrder.getId());
        orderInfoVo.setFoodOrderInfoVos(foodOrderInfoVos);
        orderInfoVo.setOrderSource(1);
        orderInfoVos.add(orderInfoVo);
    }


    public void elmAddOrderInfoVo(List<OrderInfoVo> orderInfoVos, ElmOrder elmOrder) {
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        CopyOptions copyOptions = new CopyOptions();
        copyOptions.setIgnoreNullValue(true);
        BeanUtil.copyProperties(elmOrder, orderInfoVo, copyOptions);
        List<ElmFoodDetail> elmFoodDetailList = elmContent.elmFoodDetailService.getRepository().findByElmeOrderNumber(elmOrder.getOrderNumber());
        orderInfoVo.setFoodOrderInfoVos(elmFoodDetailList);
        orderInfoVo.setFoodOrderNumber(elmOrder.getOrderNumber());
        orderInfoVo.setOrderSource(2);
        orderInfoVos.add(orderInfoVo);
    }

    /*
     * @author drj
     * @date 2019-02-25 10:03
     * @Description ：处理退款操作
     */
    public Resp refundHandle(String foodOrderId, Integer foodOrderStatus, BigDecimal money) {
        if (ParamUtil.isBlank(foodOrderId)) {
            return new Resp(Resp.PARAM_ERROR, "订单项id为空");
        }
        FoodOrder foodOrder = foodOrderRepository.findOne(foodOrderId);
        if (foodOrder == null) {
            return new Resp(Resp.PARAM_ERROR, "订单错误");
        }
        User user = userService.getRepository().findByStoreId(foodOrder.getStoreId());
        String merchantId = user.getMerchantId();
        //如果选择同意退款
        if (4 == foodOrderStatus) {
            //获取支付订单费用
            BigDecimal payMoney = foodOrder.getActPayMoney();
            if (null == money || money.compareTo(BigDecimal.ZERO) != 1) {
                return new Resp(Resp.PARAM_ERROR, "退款金额不能为空或者小于0");
            }
            if (money.compareTo(payMoney) >= 1) {
                return new Resp(Resp.PARAM_ERROR, "退款金额不能大于付款金额");
            }
            //设置退款金额
            foodOrder.setRefundMoney(money);
            //如果该订单是线上支付
            if (1 == foodOrder.getSupporyPayWay()) {
                RestTemplate restTemplate = new RestTemplate();
                AjaxResp<String> resp = null;
                //若该订单的支付方式为支付宝
                if (1 == foodOrder.getPayWay()) {
                    AliRefundDto aliRefundDto = new AliRefundDto();
                    aliRefundDto.setMerchantId(merchantId);
                    aliRefundDto.setValue(foodOrder.getRefundMoney());
                    aliRefundDto.setOrderId(foodOrder.getOtherOrderNumber());
                    resp = restTemplate.postForObject(OrderPayConstant.ALIREFUND, aliRefundDto, AjaxResp.class);
                    if (resp.getStatus().equals(AjaxResp.Status.SUCCESS)) {
                        //改变对应菜品的状态
//                        changeFoodStatus(foodOrder);
                    } else {
                        log.error("错误信息{}，传参{}", resp.getMsg(), JacksonUtil.toJson(aliRefundDto));
                        return new Resp(Resp.PARAM_ERROR, "退款失败");
                    }
                }
                //若该订单的支付方式为微信
                if (2 == foodOrder.getPayWay()) {
                    //组装微信退款所需参数
                    RefundParam refundParam = new RefundParam();
                    refundParam.setMchId(user.getMchId());
                    refundParam.setOrgNo(user.getOrgNo());
                    refundParam.setDeviceInfo(user.getDeviceInfo());
                    refundParam.setAppKey(user.getAppKey());
                    refundParam.setNonceStr(ParamUtil.uuid());
                    refundParam.setTransactionId(foodOrder.getTradeOrderNumber());
                    //获取支付费用
                    log.info("订单id：" + foodOrder.getId() + "订单总额: " + payMoney + "退款金额: " + foodOrder.getRefundMoney());
                    refundParam.setTotalFee(Integer.valueOf(payMoney.multiply(new BigDecimal("100")).stripTrailingZeros().toPlainString()));
                    refundParam.setReturnFee(Integer.valueOf(foodOrder.getRefundMoney().multiply(new BigDecimal("100")).stripTrailingZeros().toPlainString()));
                    Map<String, String> packageParams = new TreeMap<String, String>();
                    packageParams = UnifiedOrderUtil.creatRefundParams(refundParam);
                    String sign = UnifiedOrderUtil.signMd5_2(packageParams, user.getAppKey());
                    String xml = WXPayUtil.createXML(packageParams, sign.toUpperCase());
                    log.info("发起退款接口时请求的数据:\n" + xml);
                    String result = HttpUtil.sendJsonPost(returnOrderURL, xml);
                    log.info("发起退款接口时返回的数据:\n" + result);
                    //解析返回的xml信息
                    Map<String, String> map = new HashMap<String, String>();
                    try {
                        map = WxPublicUtil.xmlToMap(result);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if ("SUCCESS".equals(map.get("return_code"))) {
                        //改变对应菜品的状态
//                        changeFoodStatus(foodOrder);
                    } else {
                        return new Resp(Resp.PARAM_ERROR, map.get("return_msg"));
                    }
                }
            }
        }
        foodOrder.setFoodOrderStatus(foodOrderStatus);
        foodOrderRepository.save(foodOrder);
        return new Resp("操作成功");
    }

    /*
     * @author drj
     * @date 2019-02-25 10:04
     * @Description :确认收款
     */
    public Resp affirmMoneyToOrder(String orderId) {
        FoodOrder foodOrder = foodOrderRepository.findOne(orderId);
        if (foodOrder == null) {
            return new Resp(Resp.PARAM_ERROR, "订单信息有误");
        }
        if (foodOrder.getFoodOrderStatus().equals(1)) {
            return new Resp(Resp.PARAM_ERROR, "该订单已经确认收款,请勿重复操作");
        }
        foodOrder.setFoodOrderStatus(1);
        foodOrderRepository.save(foodOrder);
        return new Resp("确认收款成功!");
    }

    /*
     * @author drj
     * @date 2019-02-25 10:05
     * @Description :上菜完成
     */
    public Resp foodClose(String foodOrderId) {
        if (ParamUtil.isBlank(foodOrderId)) {
            return new Resp(Resp.PARAM_ERROR, "请选择订单");
        }
        FoodOrder foodOrder = foodOrderRepository.findOne(foodOrderId);
        if (null == foodOrder) {
            return new Resp(Resp.PARAM_ERROR, "请联系管理员");
        }
        List<FoodOrderInfo> foodOrderInfos = foodOrderInfoService.getRepository().findByFoodOrderId(foodOrderId);
        List<Food> foods = new LinkedList<>();
        List<FoodReport> foodReportList = new LinkedList<>();
        for (FoodOrderInfo foodOrderInfo : foodOrderInfos) {
            Food food = foodService.findOne(foodOrderInfo.getFoodId());
            food.setActSellNum(food.getActSellNum() + 1);
            food.setVirtualSellNum(food.getVirtualSellNum() + 1);
            foods.add(food);

            FoodReport foodReport = foodReportService.getRepository().findByFoodId(foodOrderInfo.getFoodId());
            //如果之前没该菜品的报表信息则生成一个
            if (ParamUtil.isBlank(foodReport)) {
                foodReport = new FoodReport();
                foodReport.setStoreId(foodOrder.getStoreId());
                foodReport.setFoodId(foodOrderInfo.getFoodId());
                foodReport.setPlatNumber(0);
                foodReport.setElmNumber(0);
                foodReport.setMtNumber(0);
            }
            foodReport.setPlatNumber(foodReport.getPlatNumber() + new Double(foodOrderInfo.getNumber()).intValue());
            foodReportList.add(foodReport);
        }
        //保存报表信息
        foodReportService.getRepository().save(foodReportList);
        foodService.getRepository().save(foods);
        foodOrder.setFoodOrderStatus(2); //设置订单状态为已结单
        //增加vip积分
        changeCustomerVipIntegral(foodOrder.getStoreId(), foodOrder.getCustomerId(), foodOrder.getActPayMoney());
        foodOrderRepository.save(foodOrder);
        return new Resp("操作成功");
    }

    //增加vip用户积分
    public void changeCustomerVipIntegral(String storeId, String customerId, BigDecimal actPayMoney) {
        Store store = storeRepository.findOne(storeId);
        if (ParamUtil.isBlank(store.getIntegralRatio())) {
            return;
        }
        Customer customer = customerService.getRepository().findOne(customerId);
        if (ParamUtil.isBlank(customer.getCustomerInfoId())) {
            return;
        }
        CustomerInfo customerInfo = customerInfoService.findOne(customer.getCustomerInfoId());
        if (customerInfo == null) {
            return;
        }
        CustomerVip customerVip = customerVipService.getRepository().findByStoreIdAndCustomerInfoId(storeId, customerInfo.getId());
        if (customerVip == null) {
            return;
        }
        customerVip.setIntegral(customerVip.getIntegral().add(actPayMoney.multiply(store.getIntegralRatio()).setScale(2, BigDecimal.ROUND_HALF_UP)));
        customerVipService.save(customerVip);
    }

}
